/**
 * Copyright (c) 2006 RiseSoft Co.,Ltd  
 * $Header$
 */
package cn.newtest.bi.collection.formula.file.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.risesoft.risebi.collection.commons.constants.SystemConstants;
import net.risesoft.risebi.collection.formula.file.Creator;
import net.risesoft.risebi.collection.formula.generate.FormulaGenerateException;
import net.risesoft.risebi.collection.model.Template;
import net.risesoft.risebi.collection.model.TemplateFile;
import net.risesoft.risebi.collection.service.TemplateManager;
import net.risesoft.risebi.commons.miscellaneouse.FilePersistLocator;
import net.risesoft.risebi.commons.util.ExceptionUtil;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;


/**
 *
 *
 * @author <a href="mailto: chenjian@risesoft.net">陈健</a>
 * @version $Revision$
 * 
 */
public abstract class AbstractCreator implements Creator {
	
	private static Log log = LogFactory.getLog(AbstractCreator.class);
	
	private TemplateManager templateManager;
	
	@Autowired
	public void setTemplateManager(TemplateManager templateManager) {
		this.templateManager = templateManager;
	}

	protected String templateFilePath;

	public abstract String getClassName(String templateGuid);
	public abstract String getFileName(String templateFilePath,String templateGuid);
	public abstract String getPureFileName(String templateGuid);
	public abstract List<FormulaGenerateException> newFile(Template template) throws Exception;

	/* (non-Javadoc)
	 * @see net.risesoft.risebi.collection.groovy.Creator#doCreate(java.lang.String)
	 */
	public List<FormulaGenerateException> doCreate(String templateGuid) throws Exception {
		if(templateGuid==null||templateGuid.equals(""))
			return new ArrayList<FormulaGenerateException>();
		
		Template template = this.init(templateGuid);
		List<FormulaGenerateException> exceptionList = this.newFile(template);
		
		templateManager.saveObject(template);
		
		return exceptionList;
	}
	
	private Template init(String templateGuid) throws Exception {
		Template template = (Template) templateManager.getObject(Template.class, templateGuid);
		
//		在templateFile下创建templateGuid的文件夹
		if(templateFilePath==null){
			templateFilePath = FilePersistLocator.getFilePersistLocator(SystemConstants.REPORT_TEMPLATEFILE);
		}
		
		String fileName = templateFilePath + template.getGuid()+"/";
		File file = new File(fileName);
		if(!file.exists()){
			file.mkdirs();
		}
		
		return template;
	}
	
	public String getGroovyTemplateName() {
		return this.getClass().getResource("/").getFile()+"net/risesoft/risebi/collection/groovy/groovytemplate.tmp";
	}
	
	public String getJsTemplateName() {
		return this.getClass().getResource("/").getFile()+"net/risesoft/risebi/collection/groovy/javascripttemplate.tmp";
	}
	
	protected void newGroovyClass(Map<String,String> formulaMap,Template template,String type) throws Exception {
		String fileName = this.getFileName(templateFilePath, template.getGuid());
		String className = this.getClassName(template.getGuid());
		
		if(formulaMap.isEmpty()){
			File file = new File(fileName);
			if(file.exists()){
				file.delete();
			}
			return;
		}
		
		StringBuffer sb = new StringBuffer();
		Iterator<String> it = formulaMap.keySet().iterator();
		while(it.hasNext()){
			String formulaGuid = it.next();
			String formulaContent = formulaMap.get(formulaGuid);
			sb.append("//begin f").append(formulaGuid).append("\r");
			sb.append("def f").append(formulaGuid).append("(){\r");
			sb.append("faults.clear()\r");
			sb.append(formulaContent).append("\r");
			sb.append("}\r").append("//end f").append(formulaGuid).append("\r");
		}
		
		sb.append("//content//\r");
		
		InputStream is = null;
//		OutputStream os = null;
		try {
			String groovyTemplate = this.getGroovyTemplateName();
			is = new FileInputStream(groovyTemplate);
			byte[] b = new byte[is.available()];
			is.read(b);
			String templateContent = new String(b);
			templateContent = templateContent.replaceAll("#groovyClassName#", className);
			
			templateContent = templateContent.replaceAll("//content//", sb.toString());
			
			TemplateFile templateFile = template.getTemplateFile();
			
			if(type.equals("audit"))
				templateFile.setAuditGroovy(templateContent);
			else
				templateFile.setCalculateGroovy(templateContent);
			
//			os = new FileOutputStream(fileName);
//			os.write(templateContent.getBytes());
			
			String pureFileName = this.getPureFileName(template.getGuid());
		} catch (Exception e) {
			log.error(ExceptionUtil.transformException(e));
			throw e;
		} finally {
			try {
				is.close();
			} catch (Exception e2) {
				// ignored
			}
//			try {
//				os.close();
//			} catch (Exception e2) {
//				// ignored
//			}
		}
	}
	
	protected void newJsFile(Map<String,String> formulaMap,Template template) throws Exception {
		String fileName = this.getFileName(templateFilePath, template.getGuid());
//		String className = this.getClassName(templateGuid);
		
		if(formulaMap.isEmpty()){
			File file = new File(fileName);
			if(file.exists()){
				file.delete();
			}
			return;
		}
		
		StringBuffer functionSb = new StringBuffer();
		StringBuffer contentSb = new StringBuffer();
		Iterator<String> it = formulaMap.keySet().iterator();
		while(it.hasNext()){
			String formulaGuid = it.next();
			String formulaContent = formulaMap.get(formulaGuid);
			
			functionSb.append("//begin invokef").append(formulaGuid).append("\r");
			functionSb.append("f").append(formulaGuid).append("();\r");
			functionSb.append("//end invokef").append(formulaGuid).append("\r");
			
			contentSb.append("//begin f").append(formulaGuid).append("\r");
			contentSb.append("function f").append(formulaGuid).append("(){\r");
			contentSb.append(formulaContent).append("\r");
			contentSb.append("}\r").append("//end f").append(formulaGuid).append("\r");
		}
		
		functionSb.append("//functions//\r");
		contentSb.append("//content//\r");
		
		InputStream is = null;
//		OutputStream os = null;
		try {
			String jsTemplate = this.getJsTemplateName();
			is = new FileInputStream(jsTemplate);
			byte[] b = new byte[is.available()];
			is.read(b);
			String templateContent = new String(b);
			templateContent = templateContent.replaceAll("//functions//", functionSb.toString());
			
			templateContent = templateContent.replaceAll("//content//", contentSb.toString());
			
			TemplateFile templateFile = template.getTemplateFile();
			templateFile.setValidationJs(templateContent);
			
//			os = new FileOutputStream(fileName);
//			os.write(templateContent.getBytes());
			
			String pureFileName = this.getPureFileName(template.getGuid());
		} catch (Exception e) {
			log.error(ExceptionUtil.transformException(e));
			throw e;
		} finally {
			try {
				is.close();
			} catch (Exception e2) {
				// ignored
			}
//			try {
//				os.close();
//			} catch (Exception e2) {
//				// ignored
//			}
		}
	}
}
